package client

import (
	"common-api/logs"
	"common-api/message"
	"common-api/process"
	"common-api/serialization"
	"common-api/session"
	"controller-client/listener"
	"fmt"
	"log"
	"net"
)

type TcpClient struct {
	R *session.Session
}

func (t *TcpClient) DoLogin(username, password string) {
	loginReqData := &message.LoginReqData{Username: username, Password: password}
	err, bytes := serialization.JsonEncode(loginReqData)
	if err != nil {
		logs.Logger.Errorf("message encode: %v", err)
		return
	}
	msg := &message.HeaderMessage{
		Type: message.RequestType,
		Code: message.LoginRequestCode,
		Body: bytes,
	}
	t.R.WriteMessage(msg)
}

func (t *TcpClient) Register(username, nickname, password string) {
	registerReqData := &message.RegisterReqData{Username: username,
		NickName: nickname, PassWord: password}
	err, bytes := serialization.JsonEncode(registerReqData)
	if err != nil {
		logs.Logger.Errorf("message encode: %v", err)
		return
	}
	msg := &message.HeaderMessage{
		Type: message.RequestType,
		Code: message.RegisterRequestCode,
		Body: bytes,
	}
	t.R.WriteMessage(msg)
}

func (t *TcpClient) DoHeartBeat() {
	loginReqData := &message.HeartBeatReqData{Username: "admin"}
	err, bytes := serialization.JsonEncode(loginReqData)
	if err != nil {
		logs.Logger.Errorf("message encode: %v", err)
		return
	}
	msg := &message.HeaderMessage{
		Type: message.RequestType,
		Code: message.HeartRequestBeatCode,
		Body: bytes,
	}
	t.R.WriteMessage(msg)
}

func (t *TcpClient) DoReceive() {
	for {
		err := t.R.ReceiveMessage()
		if err != nil {
			logs.Logger.Errorf("message receive: %v", err)
		}
	}
}

func Start(targetAddr string) *TcpClient {
	conn, err := net.Dial("tcp", targetAddr)
	if err != nil {
		log.Fatal(err)
	}
	sess := session.NewSession(conn)
	process.RegisterResponseListener(message.CommonResponseCode, &listener.CommonListener{})
	process.RegisterResponseListener(message.LoginResponseCode, &listener.LoginListener{})
	process.RegisterResponseListener(message.PrivateChatResponseCode, &listener.PrivateChatListener{})
	return &TcpClient{sess}
}

func (t *TcpClient) Close() error {
	listener.CurrentUserName = ""
	return t.R.Conn.Close()
}

func (t *TcpClient) PrivateChat(toUser, content string) {
	if listener.CurrentUserName == "" {
		fmt.Println("system_error: you not login,do not chat")
		return
	}
	privateChatData := &message.PrivateChatReqData{FromUserName: listener.CurrentUserName,
		ToUserName: toUser, ChatMessage: content}
	err, bytes := serialization.JsonEncode(privateChatData)
	if err != nil {
		logs.Logger.Errorf("message encode: %v", err)
		return
	}
	msg := &message.HeaderMessage{
		Type: message.RequestType,
		Code: message.PrivateChatRequestCode,
		Body: bytes,
	}
	t.R.WriteMessage(msg)
}
